var Snitter = {
		
	/**
	 * Initialize Snitter
	 */
	initialize: function() {
		Snitter.ErrorHandler.initialize();
		Snitter.Login.initialize();
		
		Snitter.Messages.initialize();
		Snitter.Update.initialize();
	},
	
	/**
	 * Handles displaying lists of messages
	 */
	Messages: {
		
		updateTimer: null,
		
		initialize: function() {
			Snitter.Messages.showPublic();
			
			$("h1 a").click(function() {
				Snitter.Messages.showPublic();
				return false;
			});
		},

		/**
		 * Displays the public timeline
		 */
		showPublic: function() {
			$("#pageTitle").text("Public timeline");
			
			window.clearInterval(Snitter.Messages.updateTimer);
			Snitter.Messages.updateTimer = window.setInterval(Snitter.Messages.showPublic, 5000);
			
			Snitter.Update.hide();
		
			$("#userFollowing").fadeOut();
			$("#accountFollowing").fadeOut();
			$("#profile").fadeOut();
			
			// Retrieve the timeline
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "getPublicNewMsgList",
					size: 25 },
				dataType: "json",
				success: function(data) {
					$("#messages").html("");
					$.each(data, Snitter.Messages.displayMessage);
				}});
		},
		
		/**
		 * Displays a user and its messages
		 */
		showUser: function(userId) {
			window.clearInterval(Snitter.Messages.updateTimer);
			Snitter.Messages.updateTimer = window.setInterval("Snitter.Messages.showUser("+userId+")", 5000);

			$("#accountFollowing").fadeOut();
			Snitter.Update.hide();
			
			// Retrieve this user's info
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "getUserSimpleInfo",
					id: userId},
				dataType: "json",
				success: function(data) {
					$("#pageTitle").text(data.screenName+"'s timeline");
					
					$("#profile").html("<p><strong>"+data.screenName+"</strong><br/>" +
							"Name: " + data.name + "<br/>" +
							"Address: " + data.adress + "</p>" +
							"<p><button onClick='Snitter.Profile.follow("+userId+", \""+data.screenName+"\")'>" +
								"Follow "+data.screenName+"</button>")
						.fadeIn();
				
					
					// Add user's following list
					$("#user-following").html("");
					$.each(data.following, function(i,userId) {
						$.ajax({
							url: "snitter",
							cache: false,
							data: {
								command: "getUserSimpleInfo",
								id: userId},
							dataType: "json",
							success: function(data) {
								$("#user-following").append(
									"<li><a onClick='Snitter.Messages.showUser("+userId+")'>"+data.screenName+"</a></li>");
							}});
					});
					
					// Add user's following list
					$("#user-followers").html("");
					$.each(data.followedBy, function(i,userId) {
						$.ajax({
							url: "snitter",
							cache: false,
							data: {
								command: "getUserSimpleInfo",
								id: userId},
							dataType: "json",
							success: function(data) {
								$("#user-followers").append(
									"<li><a onClick='Snitter.Messages.showUser("+userId+")'>"+data.screenName+"</a></li>");
							}});
					});
					
					$("#userFollowing").fadeIn();
				}});

			// Retrieve all messages from this user
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "getMsgFrom",
					id: userId},
				dataType: "json",
				success: function(data) {
					$("#messages").html("");
					$.each(data, Snitter.Messages.displayMessage);
				}});
		},
		
		/**
		 * Displays a user's home timeline 
		 */
		showHome: function() {
			window.clearInterval(Snitter.Messages.updateTimer);
			Snitter.Messages.updateTimer = window.setInterval(Snitter.Messages.showHome, 5000);
			
			$("#userFollowing").fadeOut();
			
			$("#profile").html("<p><strong>"+Snitter.Login.userData.screenName+"</strong><br/>" +
					"Name: " + Snitter.Login.userData.name + "<br/>" +
					"Address: " + Snitter.Login.userData.adress + "</p>")
				.fadeIn();
			
			// Add user's following list
			$("#profile-following").html("");
			$.each(Snitter.Login.userData.following, function(i,userId) {
				$.ajax({
					url: "snitter",
					cache: false,
					data: {
						command: "getUserSimpleInfo",
						id: userId},
					dataType: "json",
					success: function(data) {
						$("#profile-following").append(
							"<li>" +
								"<a onClick='Snitter.Messages.showUser("+userId+")'>"+data.screenName+"</a>" +
								"<form onsubmit='Snitter.Profile.stopFollowing("+userId+", \""+data.screenName+"\");return false'>" +
									"<button type='submit'>Delete</button></form>" +
							"</li>");
					}});
			});
			
			// Add user's followers list
			$("#profile-followers").html("");
			$.each(Snitter.Login.userData.followedBy, function(i,userId) {
				$.ajax({
					url: "snitter",
					cache: false,
					data: {
						command: "getUserSimpleInfo",
						id: userId},
					dataType: "json",
					success: function(data) {
						$("#profile-followers").append(
							"<li><a onClick='Snitter.Messages.showUser("+userId+")'>"+data.screenName+"</a></li>");
					}});
			});
			
			$("#accountFollowing").fadeIn();

			// Fetch home timeline messages
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "getUserNewMsgList",
					id: Snitter.Login.userId},
				dataType: "json",
				success: function(data) {
					$("#pageTitle").text("Your home timeline");
					$("#messages").html("");
					Snitter.Update.show();
					$.each(data, Snitter.Messages.displayMessage);
				}
			});
			
		},
		
		
		/**
		 * Adds a single message to the list
		 */
		displayMessage: function(i, data) {
			//{"msg":{"id":3,"userId":1,"text":"Hi, my name is bouke","title":"Untitled","hour":14,"minute":16,"day":14,"month":9,"year":2009},"user":{"name":"bouke","email":"bouke","screenName":"bouke","zipCode":"bouke","adress":"bouke","following":[],"followedBy":[],"newMsgFrom":{}}}
			data.domNode = $("<li>" + data.msg.text + "<br/><small>" +
					data.msg.day + "-" + data.msg.month + "-" + data.msg.year + " " + data.msg.hour + ":" + data.msg.minute + "." +
					"</small></li>");
			$("#messages").append(data.domNode);
			
			data.domNode.prepend(
					$("<a onClick='Snitter.Messages.showUser("+data.msg.userId+")' />").html(
							"<strong>" + data.user.screenName + "</strong> "));
			
			if(data.msg.userId == Snitter.Login.userId) {
				data.domNode.append(
					$("<form><button type='submit'>delete</button></form>").submit(function() {
						Snitter.Messages.removeMessage(data);
						return false;
					}));
			}
		},
		
		/**
		 * Removes a message written by the logged in user
		 */
		removeMessage: function(data) {
			Sexy.confirm("<h1>Are you sure you want to delete this message? There is NO UNDO!</h1>", {
				textBoxBtnCancel: "Cancel",
				onComplete: function(returnvalue) {
					if (!returnvalue) {
						return;
					}
					
					data.domNode.fadeOut();	
				
					$.ajax({
						url: "snitter",
						cache: false,
						data: {
							command: "removeMsg",
							id: Snitter.Login.userId,
							msgNumber: data.msg.id},
						dataType: "text"
					});
				}});
		}
	},
	
	/**
	 * Handles writing new messages
	 */
	Update: {
		initialize: function() {
			$("#createMessageForm").submit(function(){
				$.ajax({
					url: "snitter",
					cache: false,
					data: {
						command: "addMsg",
						msg: $("#createMessageForm-text").val(),
						id: Snitter.Login.userId},
					success: function(data) {
						if(typeof(data.errorName) != "undefined") {
							Snitter.ErrorHandler.handle(data);
							return;
						}
						
						Sexy.info("<h1>Your message was posted</h1>");
						
						$("#createMessageForm-text").val("");
						Snitter.Messages.showHome();
					}
				});
				
				return false;
			});
		},
		
		show: function() {
			$("#createMessageForm").fadeIn();
		},
		
		hide: function() {
			$("#createMessageForm").fadeOut();
		}
	},
	
	
	/**
	 * Handles display the current user's profile
	 */
	Profile: {
		show: function() {
			$("#account").html(
					"<strong>Welcome, "+Snitter.Login.userData.name+"</strong><br/>" +
					"<a onClick='Snitter.Messages.showHome()'>Visit my home timeline</a>")
				.fadeIn();
		},
		hide: function() {
			$("#account").html("").hide();
		},
		
		follow: function(userId, screenName) {
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "addFollowing",
					id: Snitter.Login.userId,
					idUserToFollow: userId},
				dataType: "text",
				success: function(data) {
					Sexy.info("<h1>You are now following "+screenName+"</h1>");
					Snitter.Login.refreshUserData();
				}	
			});
		},
		
		stopFollowing: function(userId, screenName) {
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "removeFollowing",
					id: userId,
					idUserFollowing: Snitter.Login.userId},
				dataType: "text",
				success: function(data) {
					Sexy.info("<h1>You stopped following "+screenName+"</h1>");
					
					Snitter.Login.refreshUserData();
				}	
			});
		}
	},
	
	
	/**
	 * Handles session
	 */
	Login: {
		userId: null,
		userData: null,
		
		initialize: function() {
			$("#registerForm").submit(Snitter.Login.onRegisterSubmit);
			$("#loginForm").submit(Snitter.Login.onLoginSubmit);
			$("#logoutForm").submit(Snitter.Login.onLogout);

			$("#showLogin").submit(function() {
				Snitter.Login.showForm();
				return false;
			});
			
			$("#loginOverClose").submit(function() {
				Snitter.Login.hideForm();
				return false;
			});
			
			$("#showLogin").fadeIn();
		},
	
		showForm: function() {
			$("#loginOver").fadeIn();
		},
		
		hideForm: function() {
			$("#loginOver").fadeOut();
		},
		
		refreshUserData: function() {
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "getUserSimpleInfo",
					id: Snitter.Login.userId},
				dataType: "json",
				success: function(data) {
					if(typeof(data.errorName) != "undefined") {
						Snitter.ErrorHandler.handle(data);
						return;
					}

					Snitter.Login.userData = data;
				}
			});
		},
		
		onLoginSubmit: function() {
			$.ajax({
				url: "snitter?command=logIn&email="+$("#loginForm-email").val()+"&psw="+$("#loginForm-password").val(),
				cache: false,
				dataType: "json",
				success: function(data) {
					if(typeof(data.errorName) != "undefined") {
						Snitter.ErrorHandler.handle(data);
						return;
					}
					
					Snitter.Login.userId = data.id;
					
					$.ajax({
						url: "snitter",
						cache: false,
						data: {
							command: "getUserSimpleInfo",
							id: data.id},
						dataType: "json",
						success: function(data) {
							if(typeof(data.errorName) != "undefined") {
								Snitter.ErrorHandler.handle(data);
								return;
							}

							Snitter.Login.userData = data;
							
							Sexy.info("<h1>Welcome, " + data.name + "</h1>");

							Snitter.Login.hideForm();
							Snitter.Messages.showHome();
							Snitter.Profile.show();
							
							$("#showLogin").fadeOut();
							$("#logoutForm").fadeIn();
						}
					});
				}
			});
			
			return false;
		},
		
		onLogout: function() {
			Snitter.Login.userData = {};
			Snitter.Login.userId = null;
			Snitter.Update.hide();
			Snitter.Messages.showPublic();
			Snitter.Profile.hide();
			
			$("#logoutForm").fadeOut();
			
			Sexy.info("<h1>You are now logged out</h1>");
			
			$("#showLogin").fadeIn();
			
			return false;
		},
		
		onRegisterSubmit: function() {
			$.ajax({
				url: "snitter",
				cache: false,
				data: {
					command: "createUser",
					name: $("#registerForm-username").val(),
					psw: $("#registerForm-password").val(),
					screenName: $("#registerForm-screenName").val(),
					adress: $("#registerForm-address").val(),
					zipCode: $("#registerForm-zipCode").val(),
					email: $("#registerForm-email").val()},
				dataType: "text",
				success: function(data) {
					if(typeof(data.errorName) != "undefined") {
						Snitter.ErrorHandler.handle(data);
						return;
					}

					Sexy.info("<h1>Registration complete, you can now login</h1>");
				}
			});
			
			return false;
		}
	},
	
	
	/**
	 * Handles displaying error messages
	 */
	ErrorHandler: {
		initialize: function() {
			$(document).ajaxError(Snitter.ErrorHandler.onAjaxError);
		},
		handle: function(json) {
			Sexy.alert("<h1>" + json.errorName + "</h1><p>" + json.errorMsg + "</p>");
		},
		onAjaxError: function(event, request, settings, error) {
			if(typeof(error) != "undefined") {
				Sexy.alert("<h1>An error occured</h1><p>"+error+"</p>");
			} else {
				Sexy.alert("<h1>Uknown connection error occured</h1>");
			}
			$("#error").show();
		}
	}
};


$(document).ready(function() {
	Snitter.initialize();
});